<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
	<title>Panner3d</title>

	<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
	<link rel="icon" type="image/png" sizes="174x174" href="./favicon.png">

	<script src="https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/2.4.3/webcomponents-bundle.js"></script>
	<link href="https://fonts.googleapis.com/css?family=Material+Icons&display=block" rel="stylesheet"/>
	<script src="../build/Tone.js"></script>
	<script src="./js/tone-ui.js"></script>
	<script src="./js/components.js"></script>

	<style type="text/css">
		tone-play-toggle {
			margin-bottom: 10px;
		}
	</style>
</head>
<body>
	<tone-example label="3D Panning">
		<tone-loader></tone-loader>
		<div slot="explanation">
			Tone.Panner3D and Tone.Listener work together to create 3D audio. Connect your synths and sources to Panner3D and then to the master output, anything you connect to the panner will be spatialized according the position of the panner relative to the position of the listener. This example synchronizes the position of the camera with Tone.Listener and the position of each of the spheres with a track.
			<br><br>
			Note: the 3D panning effect is more effective with headphones.
		</div>

		<div id="content">
			<tone-play-toggle></tone-play-toggle>
			<tone-slider 
				label="x"
				id="xSlider"
				min="-2"
				max="2"
				value="0"
			></tone-slider>
			<tone-slider 
				id="zSlider"
				label="z"
				min="-2"
				max="2"
				value="0"
			></tone-slider>
			<tone-slider 
				id="rotation"
				label="rotation"
				min="0"
				max="6.28"
				value="0"
				units="rad"
			></tone-slider>
		</div>
	</tone-example>

	<script type="text/javascript">
		function createPlayerPlusPanner(url, positionX, positionY, positionZ) {
			const panner = new Tone.Panner3D({
				panningModel: "HRTF",
				positionX,
				positionY,
				positionZ,
			}).toDestination();

			const player = new Tone.Player({
				url,
				loop: true,
			}).connect(panner).sync().start(0);
		}
		createPlayerPlusPanner("https://tonejs.github.io/audio/berklee/taps_1c.mp3", 2, 0, 0);
		createPlayerPlusPanner("https://tonejs.github.io/audio/berklee/tinkle3.mp3", 0, 0, 2);
		createPlayerPlusPanner("https://tonejs.github.io/audio/berklee/tapping1.mp3", -2, 0, 2);
		createPlayerPlusPanner("https://tonejs.github.io/audio/berklee/thump1.mp3", -2, 0, -2);

		document.querySelector("tone-play-toggle").addEventListener("start", () => Tone.Transport.start());
		document.querySelector("tone-play-toggle").addEventListener("stop", () => Tone.Transport.stop());
		
		function setRotation(angle) {
			Tone.Listener.forwardX.value = Math.sin(angle);
			Tone.Listener.forwardY.value = 0;
			Tone.Listener.forwardZ.value = -Math.cos(angle);
		}

		document.querySelector("#xSlider").addEventListener("input", (e) => Tone.Listener.positionX.value = parseFloat(e.target.value));
		document.querySelector("#zSlider").addEventListener("input", (e) => Tone.Listener.positionY.value = parseFloat(e.target.value));
		document.querySelector("#rotation").addEventListener("input", (e) => setRotation(parseFloat(e.target.value)));

	</script>

	</style>
</body>
</html>
